/**
 * weapp-js
 * https://code.aliyun.com/jionglee/weapp_base.git
 * Copyright@ 2020 Motigo, Inc.
 *
 */
import base_request from "./base_request.js";
import request from "./request.js";
import ui from "./ui.js";

export default {
  id: "", // session_id: wapp_base自定义的id
  appid: "",
  user: {
    openid: null,
    unionid: null,
    nickname: null,
    avatar: null,
    gender: null,
    country: null,
    city: null,
    province: null,
    language: null,
  },
  __ready: false,
  /* 初始化，在app的onLaunch里面调用 */
  init(appid, login) {
    this.appid = appid;
    this._clearUser();

    return new Promise((resolve, reject) => {
      if (login) {
        this._sessionLogin().then(
          (data) => {
            this.__ready = true;
            resolve(data);
          },
          (err) => {
            reject(err);
          }
        );
      } else {
        this.__ready = true;
        resolve();
      }
    });
  },
  /* 检查是否ready */
  check() {
    return new Promise((resolve) => {
      if (this.__ready) {
        resolve();
      } else {
        let start = Date.now();
        let check_timer = setInterval(() => {
          if (this.__ready || Date.now() - start > 5 * 1000) {
            clearInterval(check_timer);
            resolve();
          }
        }, 50);
      }
    });
  },
  // 能够获取nickname、avatar、gender等信息的登录接口，如果绑定了开放平台，也可以获取到unionid
  login(opts) {
    return new Promise((resolve, reject) => {
      this._sessionLogin(true).then(
        () => {
          if (this.user.unionid && this.user.avatar) {
            resolve(this.user);
          } else {
            ui.login(opts).then(resolve, (err) => {
              console.error("login fail, err:", err);
              this._clearSessionCache();
              reject();
            });
          }
        },
        (err) => {
          err;
          reject("session login fail");
        }
      );
    });
  },
  decrpytUserInfo(encrypt_data, iv) {
    return new Promise((resolve, reject) => {
      if (this.appid && encrypt_data && iv) {
        base_request
          .post("/user/decrypt/" + this.appid, {
            encrypted_data: encrypt_data,
            iv: iv,
          })
          .then(
            (data) => {
              data.session_id = this.id;
              const session_data = {
                session_id: this.id,
                openid: data.openId,
                unionid: data.unionId,
                nickname: data.nickName,
                gender: data.gender,
                avatar: data.avatarUrl,
                country: data.country,
                city: data.city,
                province: data.province,
                language: data.language,
              };
              this._setSessionCache(session_data);
              resolve(session_data);
            },
            (err) => {
              console.error("decrypt user info fail, err:", err);
              if (err && err.ret == -3) {
                // invalid session
                this._clearSessionCache();
              }
              reject(err ? err.msg : "");
            }
          );
      } else {
        reject("invalid param");
      }
    });
  },
  // 登录，会检查session的有效性，无效则使用wx.login登录并从weapp_base中获得openid/unionid等信息
  _sessionLogin(hard_mode) {
    console.log("_sessionLogin");
    return new Promise((resolve, reject) => {
      wx.showLoading({
        title: "登录中...",
      });

      wx.getNetworkType({
        success:(res) => {
          const networkType = res.networkType;
          console.log(networkType);
          if (networkType === "none") {
            //   无网络
            wx.hideLoading();
            reject("您的网络不好，请检查网络后重试");
          } else {
            this._checkSession(hard_mode).then(
              (data) => {
                wx.hideLoading();
                resolve(data);
              },
              () => {
                this._clearUser();
                console.log('login start')
                wx.login({
                  success: (res) => {
                    wx.hideLoading();
                    console.log('login success')
                    base_request
                      .post("/auth/session/" + this.appid, {
                        code: res.code,
                      })
                      .then(
                        (data) => {
                          this._setSessionCache(data);
                          resolve(data);
                        },
                        (err) => {
                          console.error("base_request fail, err:", err);
                          reject(err);
                        }
                      );
                  },
                  fail(res) {
                    wx.hideLoading();
                    console.error("wx.login fail! err:", res);
                    reject(res);
                  },
                });
              }
            );
          }
        },
      });
    });
  },
  _checkSession(hard_mode) {
    return new Promise((resolve, reject) => {
      wx.checkSession({
        success: () => {
          this._getSessionCache(hard_mode).then(
            (data) => {
              resolve(data);
            },
            (err) => {
              err;
              reject();
            }
          );
        },
        fail() {
          reject();
        },
      });
    });
  },
  _getSessionCache(hard_mode) {
    hard_mode = hard_mode == undefined ? false : hard_mode;

    return new Promise((resolve, reject) => {
      wx.getStorage({
        key: "__session__",
        success: (res) => {
          try {
            const session_data = JSON.parse(res.data);
            session_data.create_time = session_data.create_time || 1;
            let ttl = hard_mode ? 2 * 60 : 24 * 3600; // hard模式session过期时间2分钟

            if (Date.now() / 1000.0 - session_data.create_time < ttl) {
              // 本地缓存的信息，2.5天过期
              this.id = session_data.session_id;
              const keys = [
                "openid",
                "unionid",
                "nickname",
                "avatar",
                "gender",
                "country",
                "city",
                "province",
                "language",
              ];

              keys.forEach((k) => {
                this.user[k] = session_data[k];
              });

              base_request._update_session(
                this.id,
                this.appid,
                this.user.openid,
                this.user.unionid
              );
              request._update_session(
                this.id,
                this.appid,
                this.user.openid,
                this.user.unionid
              );

              resolve(session_data);
            } else {
              reject();
            }
          } catch (e) {
            e;
            reject();
          }
        },
        fail() {
          reject();
        },
      });
    });
  },
  _setSessionCache(session_data) {
    if (session_data) {
      this.id = session_data.session_id;
      session_data.create_time = parseInt(Date.now() / 1000.0);
      wx.setStorage({
        key: "__session__",
        data: JSON.stringify(session_data),
      });

      const keys = [
        "openid",
        "unionid",
        "nickname",
        "avatar",
        "gender",
        "country",
        "city",
        "province",
        "language",
      ];

      keys.forEach((k) => {
        this.user[k] = k in session_data ? session_data[k] : null;
      });

      base_request._update_session(
        this.id,
        this.appid,
        this.user.openid,
        this.user.unionid
      );
      request._update_session(
        this.id,
        this.appid,
        this.user.openid,
        this.user.unionid
      );
    }
  },
  _clearSessionCache() {
    wx.removeStorage({
      key: "__session__",
    });
  },
  _clearUser() {
    for (let k in this.user) {
      this.user[k] = null;
    }
  },
};
